package cn.flying.cloud.base.core.configuration;

import javax.servlet.DispatcherType;

import java.util.Arrays;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.filter.CommonsRequestLoggingFilter;

import com.github.benmanes.caffeine.cache.Cache;

import cn.flying.cloud.base.common.cache.CaffeineCache;
import cn.flying.cloud.base.core.filter.XssFilter;

/**
 * 自定义配置
 *
 * @author: admin
 * @date: 2023年05月26日 16:34
 * @version: 1.0
 */
@PropertySource(value = {"classpath:application.properties", "classpath:config/application.properties"}, ignoreResourceNotFound = true)
//允许忽略不存在的文件
//@EnableAsync
@EnableCaching
@Configuration
public class FtCoreAutoConfiguration {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

//    /**
//     * 异步任务的线程池
//     *
//     * @return
//     */
//    @Bean("FtTaskExecutor")
//    public Executor threadPoolTaskExecutor() {
//        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//        //配置核心线程数
//        executor.setCorePoolSize(10);
//        //配置最大线程数
//        executor.setMaxPoolSize(20);
//        //配置队列大小
//        executor.setQueueCapacity(200);
//        executor.setKeepAliveSeconds(60);
//        //配置线程池中的线程的名称前缀
//        executor.setThreadNamePrefix("ft-async-task-");
//        executor.setAwaitTerminationSeconds(60);
//        // rejection-policy：当pool已经达到max size的时候，如何处理新任务
//        // CALLER_RUNS：不在新线程中执行任务，而是有调用者所在的线程来执行
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//        //增加MDC的线程池修饰类
//        executor.setTaskDecorator(new MDCTaskDecorator());
//        //执行初始化
//        executor.initialize();
//        if (logger.isDebugEnabled()) {
//            logger.debug("完成自定义异步任务线程池配置！");
//        }
//        return executor;
//    }

    /**
     * 全局异步异常处理器
     */
    @Bean
    public AsyncUncaughtExceptionHandler asyncExceptionHandler() {
        return (ex, method, params) -> {
            // 记录异常信息：哪个方法、什么参数、什么异常
            logger.error("异步任务执行失败，方法：{}，参数：{}", method.getName(), Arrays.toString(params), ex);
            // 发送告警
//            sendAlarm("异步任务异常：" + ex.getMessage());
        };
    }

    /**
     * 本地caffeine缓存配置
     *
     * @return
     */
    @Bean("caffeineCache")
    public Cache<String, Object> caffeineCache() {
        return CaffeineCache.caffeineCache();
    }

    /**
     * XSS 的Filter注入
     * 用来处理getParameter的参数
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean xssFilterRegistrationBean() {
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        filterRegistrationBean.setFilter(new XssFilter());
        filterRegistrationBean.setOrder(0);
        filterRegistrationBean.setDispatcherTypes(DispatcherType.REQUEST);
        filterRegistrationBean.setEnabled(true);
        filterRegistrationBean.addUrlPatterns("/*");
        return filterRegistrationBean;
    }

    /**
     * 通过spring boot内置的日志拦截过滤器打印日志
     * 需要将org.springframework.web.filter.CommonsRequestLoggingFilter的日志级别设置为debug
     *
     * @return
     */
    @Bean
    public CommonsRequestLoggingFilter loggingFilter() {
        CommonsRequestLoggingFilter filter = new CommonsRequestLoggingFilter();
        filter.setIncludeQueryString(true);
        filter.setIncludePayload(true);
        filter.setIncludeHeaders(true);
        filter.setIncludeClientInfo(true);
        filter.setMaxPayloadLength(2048);
        filter.setAfterMessagePrefix("Ft-Request-Data-");

        return filter;
    }

//    /**
//     * 配置文件上传大小限制，yml中配置这里就不启用
//     * spring:
//     *   servlet:
//     *     multipart:
//     *       # 单个文件最大上传大小
//     *       max-file-size: 10MB
//     *       # 一次请求中所有文件的最大上传大小
//     *       max-request-size: 100MB
//     * @return
//     */
//    @Bean
//    public MultipartConfigElement multipartConfigElement() {
//        MultipartConfigFactory factory = new MultipartConfigFactory();
//        // 单个文件最大上传大小
//        factory.setMaxFileSize(DataSize.ofMegabytes(10));
//        // 一次请求中所有文件的最大上传大小
//        factory.setMaxRequestSize(DataSize.ofMegabytes(100));
//        return factory.createMultipartConfig();
//    }
}
